﻿using Delphi.Mimir.Config;
using Delphi.Mimir.Data.Entities.Final;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Delphi.Mimir.Wrapper {
    public class SymbolWrapper {

        public static ICollection<Symbol> GetSymbols() {
            ICollection<Symbol> symbols = new List<Symbol>();
            using (var context = new DelphiContext()) {
                symbols = context.Symbols.ToList<Symbol>();
            }
            return symbols;
        }

        public static Symbol GetSymbol(string yahooSymbolCode) {
            Symbol sym = new Symbol();
            using(var context = new DelphiContext()) {
                sym = context.Symbols.Where(a => a.YahooCode == yahooSymbolCode).Include(a => a.Exchange).FirstOrDefault();
            }
            return sym;
        }

        public static ICollection<Symbol> GetSymbols(string exchangeCode) {
            Exchange exc = new Exchange();
            ICollection<Symbol> symbols = new List<Symbol>();

            using (var context = new DelphiContext()) {
                exc = context.Exchanges.Where(e => e.Code == exchangeCode).FirstOrDefault();

                if (exc == null) {
                    return null;
                } else {
                    symbols = GetSymbols(exc);
                }
            }
            return symbols;
        }


        public static ICollection<Symbol> GetSymbols(Exchange exchange) {
            ICollection<Symbol> symbols = new List<Symbol>();
            using (var context = new DelphiContext()) {
                symbols = context.Symbols.Where(a => a.ExchangeId == exchange.ExchangeId).ToList<Symbol>();
            }
            return symbols;
        }

        public static ICollection<Symbol> GetYahooSymbols(Exchange exchange, bool yahooFlag) {
            ICollection<Symbol> symbols = new List<Symbol>();
            using (var context = new DelphiContext()) {
                symbols = context.Symbols.Where(a => a.IsYahoo == yahooFlag && a.ExchangeId == exchange.ExchangeId).Include(a => a.Exchange).ToList<Symbol>();
            }
            return symbols;
        }

        public static ICollection<Symbol> GetYahooSymbols(bool yahooFlag) {
            ICollection<Symbol> symbols = new List<Symbol>();
            using (var context = new DelphiContext()) {
                // Bug Fix Id 4
                symbols = context.Symbols.Where(a => a.IsYahoo == yahooFlag && a.IsYahooProcessed == false).Include(a => a.Exchange).ToList<Symbol>();
            }
            return symbols;
        }

        public static ICollection<Symbol> GetNewYahooSymbols() {
            ICollection<Symbol> symbols = new List<Symbol>();
            using(var context = new DelphiContext()) {
                symbols = context.Symbols.Where(a => a.IsYahoo == true && a.IsYahooProcessed == false).Include(a => a.Exchange).ToList<Symbol>();
            }
            return symbols;    
        }

        public static void UpdateSymbol(Symbol symbol) {
            using(var context = new DelphiContext()) {
                context.Entry(symbol).State = EntityState.Modified;
                context.SaveChanges();
            }
        }

        public static DateTime GetEarliestTradeDate(Symbol symbol) {
            DateTime startDate = new DateTime();
            using(var context = new DelphiContext()) {
                try {
                    startDate = context.Quotes.Where(a => a.SymbolId == symbol.SymbolId).Min(a => a.TradeDate);
                } catch (Exception e) {
                    startDate = DateTime.UtcNow;
                }
            }
            return startDate;
        }

        public static DateTime? GatLatestTradeDate(Symbol symbol) {
            DateTime endDate = new DateTime();
            using(var context = new DelphiContext()) {
                try {
                    endDate = context.Quotes.Where(a => a.SymbolId == symbol.SymbolId).Max(a => a.TradeDate);
                } catch (Exception e) {
                    return null;
                }
            }
            return endDate;
        }

        public static List<Quote> GetQuotes(Symbol symbol, Frequency frequency, DateTime startDate, DateTime endDate) {
            List<Quote> quotes = new List<Quote>();
            using(var context = new DelphiContext()) {
                quotes = context.Quotes.Where(a => a.SymbolId == symbol.SymbolId
                    && a.FrequencyId == frequency.CategoryId
                    && a.TradeDate >= startDate
                    && a.TradeDate <= endDate).ToList();
            }
            return quotes;
        }

        public static Quote GetQuoteByLatestDate(Symbol symbol, Frequency freq, DateTime tradeDate) {
            Quote q = new Quote();
            using (var context = new DelphiContext()) {
                q = context.Quotes.Where(a => a.SymbolId == symbol.SymbolId
                    && a.FrequencyId == freq.CategoryId
                    && a.TradeDate <= tradeDate).OrderByDescending(a => a.TradeDate).FirstOrDefault();
            }
            return q;
        }

        public static void AddQuote(Symbol symbol, Quote quote) {
            using (var context = new DelphiContext()) {
                context.Quotes.Add(quote);
            }
        }

        public static void AddQuotes(Symbol symbol, List<Quote> quotes) {
            using(var context = new DelphiContext()) {
                context.Quotes.AddRange(quotes);
            }
        }
    }
}
